﻿using SuperMap.Data;
using SuperMap.Realspace;
using SuperMap.Realspace.NetworkAnalyst;
using System;
using System.Diagnostics;
using System.Drawing;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using Ycjw.PipeLine.Map.Basic.Conditions;
using Ycjw.PipeLine.Map.Basic.SuperMap;

namespace Ycjw.PipeLine.Map.Tools.Conditions
{
    /// <summary>
    /// 爆管分析-在数据中已经存在网络数据集
    /// </summary>
    public class BGAnalystToolBar:BasicToolBar
    {
        FacilityAnalyst3D m_FacilityAnalyst3D;
        FacilityAnalystSetting3D m_FacilityAnalystSetting3D;
        Selection3D m_Selection3D;
        private void CreateFacilityAnalyst3D()
        {
            m_FacilityAnalyst3D = new FacilityAnalyst3D();
            m_FacilityAnalystSetting3D = new FacilityAnalystSetting3D
            {
                EdgeIDField = "SMID",
                NodeIDField = "SSNODEID",
                FNodeIDField = "SSFNODE",
                TNodeIDField = "SSTNODE"
            };

            WeightFieldInfo3D weightFieldInfo = new WeightFieldInfo3D
            {
                Name = "Length",
                FTWeightField = "SMLENGTH",
                TFWeightField = "SMLENGTH"
            };
            WeightFieldInfos3D weightFieldInfos = new WeightFieldInfos3D
            {
                weightFieldInfo
            };
            m_FacilityAnalystSetting3D.WeightFieldInfos = weightFieldInfos;
        }
        public BGAnalystToolBar():base()
        {
            CreateFacilityAnalyst3D();
            this.ConditionPanelName = "爆管分析";

            var annlystToolStripButtonSelect = new ToolStripButton()
            {
                DisplayStyle = ToolStripItemDisplayStyle.ImageAndText,
                Text = "选择爆管位置",
                Name = "preAnalyst"
            };
            base.ToolStrip.Items.Add(annlystToolStripButtonSelect);

            var annlystToolStripButton = new ToolStripButton()
            {
                DisplayStyle = ToolStripItemDisplayStyle.ImageAndText,
                Text = "爆管分析",
                Name = "Analyst"
            };
            base.ToolStrip.Items.Add(annlystToolStripButton);

            annlystToolStripButtonSelect.Click += AnnlystToolStripButtonSelect_Click;
            annlystToolStripButton.Click += AnnlystToolStripButton_Click;

        }

        protected override void OnLoad(EventArgs e)
        {
            this.SceneControl.ObjectSelected -= SceneControl_ObjectSelected;
            this.SceneControl.ObjectSelected += SceneControl_ObjectSelected;
            RegisterEvent();
        }
        private void SceneControl_ObjectSelected(object sender, SuperMap.UI.ObjectSelectedEventArgs e)
        {
            if (e.Count <= 0)
            {
                m_Selection3D = null;
                return;
            }
            Selection3D[] selection3d = SceneControl.Scene.FindSelection(true);
            m_Selection3D = selection3d[0];
            var selectFeature = m_Selection3D.ToRecordset();
            if (selectFeature.GetGeometry().Type != GeometryType.GeoLine3D)
            {
                Sunny.UI.UIMessageTip.Show("请选中一条管线设置爆管位置");
                m_Selection3D.Clear();
                return;
            }
            var lyr = selection3d[0].Layer;
            if (!(lyr is Layer3DDataset)) return ;
            Layer3DDataset layer3DDataset = lyr as Layer3DDataset;

            var datasetVectorNetWork = FindNetWorkNodeLayerByLineLayer(layer3DDataset.Dataset);
            m_FacilityAnalystSetting3D.NetworkDataset = datasetVectorNetWork;
            m_FacilityAnalyst3D.AnalystSetting = m_FacilityAnalystSetting3D;
        }

        private DatasetVector FindNetWorkNodeLayerByLineLayer(Dataset dataset)
        {
            foreach (Dataset dset in dataset.Datasource.Datasets)
            {
                if (dset.Type != DatasetType.Network3D) continue;

                DatasetVector dsv = dset as DatasetVector;

                return dsv;
            }
            return null;
        }

        private void AnnlystToolStripButton_Click(object sender, EventArgs e)
        {
            this.Scene.TrackingLayer.Clear();
            if(m_Selection3D == null || m_Selection3D.Count == 0)
            {
                return;
            }
            var recordSet = m_Selection3D.ToRecordset();
            var edgeID = recordSet.GetInt16("SmID");
            var fNodeID = recordSet.GetInt16("SSFNODE");
            var tNodeID = recordSet.GetInt16("SSTNODE");
            m_FacilityAnalyst3D.Load();
            var result = m_FacilityAnalyst3D.BurstAnalyseFromEdge(new int[] { fNodeID , tNodeID }, edgeID, true);

            var networkDataSet = m_FacilityAnalyst3D.AnalystSetting.NetworkDataset;
            var nodeDataSet = networkDataSet.ChildDataset;

            var keyPoints = result.CriticalNodes;
            var allNodeFeatures = nodeDataSet.GetAllFeatures();
            var labekKeyPoint = "关键设施点";
            foreach (var p in keyPoints)
            {
                var f = allNodeFeatures[p];
                var gp3d = f.GetGeometry() as GeoPoint3D;
                var markerPath = Commons.Paths.ApplicationResourcesDir + "\\Symbols\\downArrow.gif";

                var marderStyle = new GeoStyle3D()
                {
                    MarkerColor = Color.Green,
                    MarkerSize = 20,
                    MarkerFile = markerPath,
                    AltitudeMode = AltitudeMode.Absolute,
                    MarkerScale = 0.25
                };
                if (!string.IsNullOrEmpty(labekKeyPoint))
                {
                    var textLocation = gp3d.InnerPoint3D;
                    GeoText3D geoText = new GeoText3D(new TextPart3D(labekKeyPoint, textLocation));
                    Styles.SetResultTextStyle(geoText);
                    geoText.TextStyle.ForeColor = Color.Green;
                    geoText.TextStyle.FontHeight = 6;
                    Scene.TrackingLayer.Add(geoText, "");
                    gp3d.Style3D = marderStyle;
                    Scene.TrackingLayer.Add(gp3d, "");
                }
            }

            var allLineFeatures = networkDataSet.GetAllFeatures();
            var edges = result.Edges;
            var labeLine = "影响管段";
            foreach (var line in edges)
            {
                var f = allLineFeatures[line];
                var gl3d = f.GetGeometry() as GeoLine3D;

                var lineStyle = new GeoStyle3D()
                {
                    AltitudeMode = AltitudeMode.Absolute,
                    LineColor = Color.Yellow,
                    LineWidth = 6
                };
                if (!string.IsNullOrEmpty(labeLine))
                {
                    var textLocation = gl3d.InnerPoint3D;
                    GeoText3D geoText = new GeoText3D(new TextPart3D(labeLine, textLocation));
                    Styles.SetResultTextStyle(geoText);
                    Scene.TrackingLayer.Add(geoText, "");
                    gl3d.Style3D = lineStyle;
                    Scene.TrackingLayer.Add(gl3d, "");
                }
            }

            var normalNodes = result.NormalNodes;
            var normalNodeLabel = "";
            foreach (var p in normalNodes)
            {
                var f = allNodeFeatures[p];
                var gp3d = f.GetGeometry() as GeoPoint3D;
                var markerPath = Commons.Paths.ApplicationResourcesDir + "\\Symbols\\downArrow.gif";

                var marderStyle = new GeoStyle3D()
                {
                    MarkerColor = Color.Blue,
                    MarkerSize = 32,
                    MarkerFile = markerPath,
                    AltitudeMode = AltitudeMode.Absolute,
                    MarkerScale = 0.25
                };
                if (!string.IsNullOrEmpty(normalNodeLabel))
                {
                    var textLocation = gp3d.InnerPoint3D;
                    GeoText3D geoText = new GeoText3D(new TextPart3D(normalNodeLabel, textLocation));
                    Styles.SetResultTextStyle(geoText);
                    Scene.TrackingLayer.Add(geoText, "");
                    gp3d.Style3D = marderStyle;
                    Scene.TrackingLayer.Add(gp3d, "");
                }
            }
        }

        public override void AfterClose()
        {
            Scene.TrackingLayer.Clear();
            SceneControl.MouseUp -= new System.Windows.Forms.MouseEventHandler(SceneControl_MouseUp);
            this.SceneControl.ObjectSelected -= SceneControl_ObjectSelected;
        }
        // 判断是否为绘制状态
        // Whether it is editable
        public bool isDraw = false;
        // 判断是否注册鼠标点击事件
        // Whether to register mouse clicking event
        public bool isRegistered = false;
        private GeoParticle m_geoParticle = null;

        // 控制鼠标事件的注册与注销
        // Register and logoff for control mouse 
        public void RegisterEvent()
        {
            SceneControl.MouseUp -= new System.Windows.Forms.MouseEventHandler(SceneControl_MouseUp);
            SceneControl.MouseUp += new System.Windows.Forms.MouseEventHandler(SceneControl_MouseUp);
        }

        void SceneControl_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e)
        {
            try
            {
                // 左键抬起且鼠标状态为绘制状态时
                // The left key picks and the mouse state is drawn
                if (e.Button == System.Windows.Forms.MouseButtons.Left)
                {
                    Point3D m_point3D = new Point3D();
                    m_point3D = SceneControl.Scene.PixelToGlobe(new Point(e.X, e.Y), PixelToGlobeMode.TerrainAndModel);
                    GeoPoint3D m_geoPoint3D = new GeoPoint3D(m_point3D);
                    CreateParticles(m_geoPoint3D);
                }
                else
                {
                    return;
                }

                Task.Factory.StartNew(() => {
                    Thread.Sleep(200);
                }).ContinueWith((t) => {
                    if (m_geoParticle == null)
                    {
                        this.Scene.TrackingLayer.Clear();
                        return;
                    }
                    var sel = SceneControl.Scene.FindSelection(true);
                    if (sel == null || sel.Length == 0)
                    {
                        this.Scene.TrackingLayer.Clear();
                        return;
                    }
                    if (m_Selection3D == null) return;
                    Geometry3D geometry3D = m_Selection3D.ToRecordset().GetGeometry() as Geometry3D;
                    var post = m_geoParticle.Position;
                    post.Z = geometry3D.InnerPoint3D.Z;
                    this.Scene.TrackingLayer.Clear();
                    this.Scene.TrackingLayer.Add(m_geoParticle, "");
                }, TaskScheduler.FromCurrentSynchronizationContext());
            }
            catch (System.Exception ex)
            {
                Trace.WriteLine(ex.Message);
            }
        }

        /// <summary>
        /// 在传入的目标点处创建对应的火焰、喷泉、烟雾、爆炸、尾焰、烟火、烟花等粒子对象
        /// Create the fire, fountains, smoke, explosion, tall flame, firework and other particles in the imported target point
        /// </summary>
        public void CreateParticles(GeoPoint3D point3D)
        {
            GeoStyle3D particleStyle = new GeoStyle3D
            {
                AltitudeMode = AltitudeMode.Absolute
            };
            if (point3D == null || double.IsNaN(point3D.X) || double.IsNaN(point3D.Y))
            {
                return;
            }
            // 创建喷泉
            // Fountain
            m_geoParticle = new GeoParticle(ParticleType.Fountain, point3D)
            {
                Style3D = particleStyle
            };
        }
        private void AnnlystToolStripButtonSelect_Click(object sender, EventArgs e)
        {
            m_geoParticle = null;
            Scene.TrackingLayer.Clear();
        }
    }
}
